package design_patterns

import (
	"fmt"
)

type Observer interface {
	Update(forward string)
	TestRange(forward string) bool
}

type Observered struct {
	ObserverList []Observer
}

func (o *Observered) AddObserver(ob Observer) {
	o.ObserverList = append(o.ObserverList, ob)
}

func (o *Observered) NotifyAll(forward string) {
	for _, ob := range o.ObserverList {
		ob.Update(forward)
	}
}

type Hero struct {
	Observered
}

func NewHero() Hero {
	return Hero{Observered{make([]Observer, 0)}}
}

func (h Hero) Move(forward string) {
	h.NotifyAll(forward)
}

type Trap struct{}

func NewTrap() Trap {
	return Trap{}
}

func (t Trap) Update(forward string) {
	if t.TestRange(forward) {
		fmt.Println("陷阱干掉了主角")
	}
}

func (t Trap) TestRange(forward string) bool {
	return forward == "w"
}

type Drug struct{}

func NewDrug() Drug {
	return Drug{}
}

func (d Drug) Update(forward string) {
	if d.TestRange(forward) {
		fmt.Println("毒药毒死了主角")
	}
}

func (d Drug) TestRange(forward string) bool {
	return forward == "d"
}

//test case

/*func TestAdapter(t *testing.T){
	drug := NewDrug()
	trap := NewTrap()
	hero := NewHero()

	hero.AddObserver(drug)
	hero.AddObserver(trap)
	hero.Move("w")
	hero.Move("s")
}*/
